<?php
class Application_Model_Actions extends Xend_Db_Model {
	protected $_dbTableName = 'Application_Model_Table_Actions';

	public function __construct() {
		parent::__construct();
	}

	public function find($where, $ref = array(), Application_Model_Schema_Actions $action = null) {
		$action = null;

		if(is_array($data = $this->findall($where, $ref, array('limit' => 1)))) {
			$action = current($data);
		}

		return $action;
	}

	/**
	 * liesst alle Aktionen, anhand der uebergebenen Bedingungen aus
	 * @param array $where Array mit Bedingungen, die an die Datenbank uebergeben werden
	 * @param array $ref Array mit Tabellen, die verknuepft werden sollen
	 * @return array Array mit den Daten, die aus der Datenbank geladen wurden
	 */
	public function findall($where = array(), $ref = array()) {
		$actions	= array();
		$ref			= array_flip($ref);
		$select		= $this->_database
			->select()
			->from(
				array('actions'),
        array('actions.id', 'actions.hid', 'actions.name', 'actions.execution_time')
			)
			->order(array('actions.id'));

		// Where
		// -----------------------------------------------------------------------------------
		if(is_array($where) && !empty($where)) {
			foreach($where as $k => $v) {
				$select->where($k, $v);
			}
		}

		// Datenauswertung
		// -----------------------------------------------------------------------------------
		foreach($this->fetch($select) as $k => $v) {
			$action	= new Application_Model_Schema_Action();
			$action
				->setId($v['actions']['id'])
				->setHid($v['actions']['hid'])
				->setName($v['actions']['name'])
				->setExecutionTime($v['actions']['execution_time']);

			$actions[(int) $v['actions']['id']] = $action;
		}

		// -----------------------------------------------------------------------------------
		// Referenzen verknuepfen
		if(!empty($ref)) {
			if(array_key_exists('ActionValueResources', $ref)) {
				$actions = $this->_assignValueResourceReferences($actions);
			}
			if(array_key_exists('ActionValueObjects', $ref)) {
				$actions = $this->_assignValueObjectReferences($actions);
			}
		}

		return $actions;
	}

	/**
	 * laedt alle Aktionswerte (Rate), je nach Typ (Verbrauch action_use_resources /
	 * Produktion action_produce_resources) aus der Datenbank
	 * @param string $type use|produce
	 * @param type $where
	 * @param type $ref
	 */
	public function findallValueResources($type, $where = array(), $ref = array()) {
		$valueTable			= 'action_' . $type . '_resources';
		$ref						= array_flip($ref);
		$valueResources = array();
		$select					= $this->_database
			->select()
			->from(
				array($valueTable),
        array($valueTable . '.actions_id', $valueTable . '.resources_id', $valueTable . '.rate', $valueTable . '.value')
			);

		// Where
		// -----------------------------------------------------------------------------------
		if(is_array($where) && !empty($where)) {
			foreach($where as $k => $v) {
				$select->where($k, $v);
			}
		}

		// Datenauswertung und Verknuepfung mit dem Schema
		// -----------------------------------------------------------------------------------
		foreach($this->fetch($select) as $k => $v) {
			$valueResource = new Application_Model_Schema_ActionValueResource();
			$valueResource
				->setId($v[$valueTable]['resources_id'])
				->setRate($v[$valueTable]['rate'])
				->setValue($v[$valueTable]['value']);

			$valueResources[(int) $v[$valueTable]['actions_id']][(int) $v[$valueTable]['resources_id']] = $valueResource;
		}

		return $valueResources;
	}


	/**
	 * laedt alle Aktionswerte von Objekten, je nach Typ (Verbrauch action_use_objects /
	 * Produktion action_produce_objects) aus der Datenbank
	 * @param string $type use|produce
	 * @param type $where
	 * @param type $ref
	 */
	public function findallValueObjects($type, $where = array(), $ref = array()) {
		$valueTable		= 'action_' . $type . '_objects';
		$ref					= array_flip($ref);
		$valueObjects = array();
		$select				= $this->_database
			->select()
			->from(
				array($valueTable),
        array($valueTable . '.actions_id', $valueTable . '.objects_id', $valueTable . '.value')
			);

		// Where
		// -----------------------------------------------------------------------------------
		if(is_array($where) && !empty($where)) {
			foreach($where as $k => $v) {
				$select->where($k, $v);
			}
		}

		// Datenauswertung und Verknuepfung mit dem Schema
		// -----------------------------------------------------------------------------------
		foreach($this->fetch($select) as $k => $v) {
			$valueObject = new Application_Model_Schema_ActionValueObject();
			$valueObject
				->setId($v[$valueTable]['objects_id'])
				->setValue($v[$valueTable]['value']);

			$valueObjects[(int) $v[$valueTable]['actions_id']][(int) $v[$valueTable]['objects_id']] = $valueObject;
		}

		return $valueObjects;
	}

	/**
	 * verknuepft die, per Array uebergebenen, Aktion-Eintraege mit den Daten der
	 * referenzierten ResourceValues (action_use_resources, action_produce_resources)
	 * @param array $sources Array mit den Daten der Aktionen
	 * @param array $references optionales Array mit den UID der Aktionen
	 * @return array Array der Aktionen mit den verknuepften ResourceValues-Eintraegen
	 */
	protected function _assignValueResourceReferences($sources, $references = array()) {
		if(empty($references)) {
			foreach($sources as $source) {
				$references[] = $source->id;
			}
		}

		// Use-Resources laden
		$useResourcesWhere	= array('action_use_resources.actions_id IN (?)' => $references);
		$useResources				= $this->findallValueResources('use', $useResourcesWhere);

		// Reduce-Resources laden
		$produceResourcesWhere	= array('action_produce_resources.actions_id IN (?)' => $references);
		$produceResources				= $this->findallValueResources('produce', $produceResourcesWhere);

		// Use- / Produce-Resources verknuepfen
		foreach($sources as $source) {
			if(array_key_exists($source->id, $useResources)) {
				$source->use->setResources($useResources[$source->id]);
			}
			if(array_key_exists($source->id, $produceResources)) {
				$source->produce->setResources($produceResources[$source->id]);
			}
		}

		return $sources;
	}


	/**
	 * verknuepft die, per Array uebergebenen, Aktion-Eintraege mit den Daten der
	 * referenzierten ObjectValues (action_use_objects, action_produce_objects)
	 * @param array $sources Array mit den Daten der Aktionen
	 * @param array $references optionales Array mit den UID der Aktionen
	 * @param string $type Typ der verknuepften Objekte: use oder produce
	 * @return array Array der Aktionen mit den verknuepften ObjectValues-Eintraegen
	 */
	protected function _assignValueObjectReferences($sources, $references = array(), $type = null) {
		if(empty($references)) {
			foreach($sources as $source) {
				$references[] = $source->id;
			}
		}

		// Use-Resources laden
		if($type === null || $type === 'use') {
			$useObjectsWhere	= array('action_use_objects.actions_id IN (?)' => $references);
			$useObjects				= $this->findallValueObjects('use', $useObjectsWhere);
		}

		// Reduce-Resources laden
		if($type === null || $type === 'produce') {
			$produceObjectsWhere	= array('action_produce_objects.actions_id IN (?)' => $references);
			$produceObjects				= $this->findallValueObjects('produce', $produceObjectsWhere);
		}

		// Use- / Produce-Resources verknuepfen
		foreach($sources as $source) {
			if(isset($useObjects) && array_key_exists($source->id, $useObjects)) {
				$source->use->setObjects($useObjects[$source->id]);
			}
			if(isset($produceObjects) && array_key_exists($source->id, $produceObjects)) {
				$source->produce->setObjects($produceObjects[$source->id]);
			}
		}

		return $sources;
	}
}
?>